package personal;


import exceptions.*;
import personal.parser.*;
import personal.scanner.MyScanner;

import java.io.FileOutputStream;
import java.util.List;

/**
 * 只是测试程序
 */
class TestDrive {

    /**
     * 测试函数
     */
    public static void main(String[] args) throws IllegalIdentifierException, IllegalSymbolException, IllegalDecimalException, SyntacticException {
//        System.out.println(((SimpleScannerDFA) new SimpleFactory().makeScannerDFA()).toMermaid());
//        test1();
//        test2();
//        test3();
//        Factory factory = new SimpleFactory();
//        MyScanner myScanner = factory.makeScanner();
//        MyParser myParser = factory.makeParser();
//        String expression = "sin(2)";

//        System.out.println(m);

        String[] expressions = new String[]{
//                "(5 > 3) ? 15 : 16",
//                "(5 > 3) & (4 < 8) ? 15 : 16"
//                "(2 + 3) ^ 3) - ((1 + 1)"
//                "((2 + 3) ^ ((3 - 1) + 1))",
//                "((2 + 3) ^ ((3 - 1) + 1)"
                "1 + 2"
//                "1+max((1*2 > 1 ? 1: 0) + 1)"
        };
        for (String expression : expressions) {
            System.out.println(test4(expression));
        }
        System.out.println("finish");
    }

    static MyScanner myScanner = new SimpleFactory().makeScanner();
    static MyParser myParser = new SimpleFactory().makeParser();

    public static String test4(String expression) {
        try {
            List<MyScanner.Token> tokens = myScanner.scan(expression);
//            System.out.println(tokens);
            return myParser.parser(tokens);
        } catch (ExpressionException e) {
            return e.toString();
        }
//        return "accept";
    }


    public static void test3() {
        Factory factory = new SimpleFactory();
        Grammar grammar = factory.makeGrammar();
//        System.out.println(grammar.fist(grammar.getSymbol("S")));
        ParserFA fa = new SimpleParserFA(grammar);
        writeFile(fa.toString(), "parserFA");
        System.out.println(fa.size());
//        for (int i = 1; i <= fa.size(); ++i) {
//            ParserFA.Status status = fa.getStatus(i);
//            System.out.println(List.of(i, status.isReducible(), status.haveRRConflict(), status.haveSRConflict()));
//        }
        ParserTable parserTable = factory.makeParserTable();
//        System.out.println(parserTable);
    }

    /**
     * really Scanner DFA
     */
    public static void test2() {

//        System.out.println(MyScanner.DFA.toMermaid());
//        System.out.println(MyScanner.DFA.getAcceptNodes());
    }


    /**
     * STRE to NFA
     */
    public static void test1() {
//        String digit = "0-9";
//        String integral = String.format("(%s)(%s)*", digit, digit); // 整数
//        String fraction = String.format(".(%s)", integral); // 小数
//        String exponent = String.format("(E|e)(+|\\-|\\e)(%s)", integral); // 指数
//        String decimal = String.format("(%s)((%s)|\\e)((%s)|\\e)", integral, fraction, exponent); // 浮点数
//        String numericTypeRE = String.format("(%s)|(%s)", integral, decimal); // 数值类型
//
//        String booleanTypeRE = String.format("(%s)|(%s)", "true", "false"); // 布尔类型
//
//        String arithmeticOperator = String.format("(%s)|(%s)|(%s)|(%s)|(%s)", "+", "\\-", "\\*", "/", "^"); // 算术运算符
//
//        String comparisonOperator = String.format("(%s)|(%s)|(%s)|(%s)|(%s)|(%s)", ">", "<", "=", ">=", "<=", "<>"); // 比较运算符
//        String relationalOperator = String.format("(%s)|(%s)|(%s)", "&", "\\|", "!"); // 关系运算符
//        String booleanOperator = String.format("(%s)|(%s)", comparisonOperator, relationalOperator); // 布尔运算符
//
//        String otherOperator = String.format("(%s)|(%s)|(%s)|(%s)|(%s)", "?", ":", ",", "\\(", "\\)"); // 三目运算符、逗号运算符、括号运算符
//        String operatorTypeRE = String.format("(%s)|(%s)|(%s)", arithmeticOperator, booleanOperator, otherOperator);// 上述三种运算符
//
//        String functionTypeRE = String.format("(%s)|(%s)|(%s)|(%s)", "sin", "cos", "max", "min");
//
//        String finalRE = String.format("(%s)|(%s)|(%s)|(%s)", numericTypeRE, booleanTypeRE, operatorTypeRE, functionTypeRE);
//
//        String[] testcases = new String[]{numericTypeRE, booleanTypeRE, operatorTypeRE, functionTypeRE, finalRE};
//
//        for (int i = 0; i < testcases.length; ++i) {
//            String testcase = testcases[i];
//            ScannerFiniteAutomata dfa = new ExREToMinDFAConverter().convert(testcase, 1, 1);
//            writeFile(dfa.toMermaid(), i);
//        }

    }

    /**
     * 写文件
     *
     * @param str         文件内容
     * @param information 不带后缀的文件名，若传入 int，那么将转换成 output%d
     */
    public static void writeFile(String str, Object information) {
        String fileName;
        if (information instanceof Integer) fileName = String.format("./test_output/output%d.md", information);
        else if (information instanceof String) fileName = String.format("./test_output/%s.md", information);
        else throw new IllegalArgumentException("错误的参数类型");

        try (FileOutputStream fout = new FileOutputStream(fileName)) {
            fout.write(str.getBytes()); // 文件输出
        } catch (Exception e) {
            System.out.println(str);
        }
    }


}
